package com.zzedu.framework.security;

import com.zzedu.common.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.CookieSerializer.CookieValue;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionIdResolver;

import java.util.Collections;
import java.util.List;

/**
 * 同时支持 cookie 和 header 传递
 *
 * @author Administrator
 */
public class HeaderAndCookieHttpSessionStrategy implements HttpSessionIdResolver {
    public static final String WRITTEN_SESSION_ID_ATTR = CookieHttpSessionIdResolver.class.getName().concat(".WRITTEN_SESSION_ID_ATTR");
    public static final String HEADER_X_AUTH_TOKEN = "X-AUTH-TOKEN";

    /**
     * 请求平台 app 、pc、wxmini
     */
    public static final String PLATFORM  = "platform";


    private CookieSerializer cookieSerializer = new DefaultCookieSerializer();

    /**
     * Sets the {@link CookieSerializer} to be used.
     *
     * @param cookieSerializer the cookieSerializer to set. Cannot be null.
     */
    public void setCookieSerializer(CookieSerializer cookieSerializer) {
        if (cookieSerializer == null) {
            throw new IllegalArgumentException("cookieSerializer cannot be null");
        }
        this.cookieSerializer = cookieSerializer;
    }

    @Override
    public List<String> resolveSessionIds(HttpServletRequest request) {
        String headerValue = request.getHeader(HEADER_X_AUTH_TOKEN);
        if (!StringUtils.isEmpty(headerValue)) {
            return Collections.singletonList(headerValue);
        }
        return this.cookieSerializer.readCookieValues(request);
    }

    @Override
    public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
        response.setHeader(HEADER_X_AUTH_TOKEN, sessionId);
        if (!sessionId.equals(request.getAttribute(WRITTEN_SESSION_ID_ATTR))) {
            request.setAttribute(WRITTEN_SESSION_ID_ATTR, sessionId);
            this.cookieSerializer.writeCookieValue(new CookieValue(request, response, sessionId));
        }
    }

    @Override
    public void expireSession(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader(HEADER_X_AUTH_TOKEN, "");
        this.cookieSerializer.writeCookieValue(new CookieValue(request, response, ""));
    }
}
